// -*-c#-*-
// License: New BSD License : http://www.opensource.org/licenses/bsd-license.php
//
// Copyright (c) 2008, Brothers In Arms/Burl Nyswonger
//
// See: BiaVote.uc for full License
// 
//@L

class BiaVoteDataClient extends ReplicationInfo
    Config(BiaVote);

//TODO: move the welcome screen crap out of here - it don't belong.

/* ------------------------------------------------------------------------- */

`include( BiaVote/Classes/BiaStdInc.uci );
`include( BiaVote/Classes/BiaVote.uci );

/* ------------------------------------------------------------------------- */


struct BiaVoteUIData
{
    var int Index;
    var string Tag, Value, List;
};


// server side
// Config File...
var config array<BiaVoteUIData> UIData;
var config array<string>        WelcomeText;
// Cleaned-up Config Data...
var array<BiaVoteUIData>        aUIData;
var int                         StatelessTimer;

// client side...
var LocalPlayer                 LP;  // also used in "Default Instance" - see below
//                                      Note: this shouldn't effect GC on the client.
var BiaVoteDataStore            Store;
var bool                        bWelcome, bMenuClosed, bShowWelcome;
var float                       fTickTime, fLastSceneTick;

// client/server side...
var int                         SendIndex;
var PlayerController            MyPlayerController;
var float                       TickTotal;

// ---------------------------------------------------------------------------

// ugh... I should have made a base class from UTUIFrontEnd for my scene classes - doh!
// ugh...  Todo: use UTTabPage next time - it has an OnTick()
`if(`isdefined(MY_SCENE_TICKER))
reliable client function TickTheScenes( coerce int t )
{
    local BiaVoteWelcomeScene sW;
    local BiaVoteScene sV;
    
    `BiaDbg("Ticking Scenes...");
    
    sW = BiaVoteWelcomeScene(FindObject("BiaVoteWelcomeScene_0", class'BiaVote.BiaVoteWelcomeScene'));
    sV = BiaVoteScene(FindObject("BiaVoteScene_0", class'BiaVote.BiaVoteScene'));
    if( sW != None )
    {
        sW.MyTick(t);
    }
    if( sV != None )
    {
        sV.MyTick(t);
    }
}
`endif

function Timer()
{
    StatelessTimer++;
    if(StatelessTimer > 10)
    {
        ClearTimer();
        GotoState('AllDone');
    }
}

state AllDone
{
    function BeginState( name PrevState )
    {
        MyPlayerController = None;  // important for GC!
        SetTimer(1.0);
        Welcome();
    }
    function Timer()
    {
        Welcome();
    }
}

reliable server function ShowedWelcome()
{
    ClearTimer();
}

simulated function Tick( float DeltaTime )
{
    local UTGameReplicationInfo GRI;
        
    if( ROLE != ROLE_Authority )
    {
        if( !bMenuClosed )
        {
            `BiaDbg("Client Tick: " $ DeltaTime );
            GRI = UTGameReplicationInfo(WorldInfo.GRI);
            if ( GRI != none && GRI.CurrentMidGameMenu != none )
            {

`if(`notdefined(MY_SCENE_TICKER))                
                disable('Tick');
`endif    
                `BiaDbg("Closing MidGameMenu");
                GRI.CurrentMidGameMenu.CloseScene(GRI.CurrentMidGameMenu);
                bMenuClosed = true;
                fTickTime = 0.0f;
                fLastSceneTick = 0.0f;
            }
            return;
        }

`if(`isdefined(MY_SCENE_TICKER))        
        fTickTime += DeltaTime;
        if( (fTickTime - fLastSceneTick) > 2.0f )
        {
            fLastSceneTick = fTickTime;
            TickTheScenes( fTickTime );
        }
`endif

    }
    else
    {
        `BiaDbg("server? Tick");
        disable('Tick');
    }

`if(`notdefined(MY_SCENE_TICKER))
    //fail-safe tick shutdown...
    TickTotal += DeltaTime;
    if( TickTotal > 10 )
    {
        disable('Tick');
    }
`endif
    
}

reliable client function Welcome()
{
//    local int i;
//    local string o;
//    local UTUIScene_MidGameMenu Mnu;
    local GameUISceneClient SceneClient;
    local UTGameReplicationInfo GRI;

    if( !bWelcome )
    {
        bWelcome = true;
        ShowedWelcome();

/* this don't work - lol...
        for(i=0; i< 10; i++)
        {
            //TODO: get the actual class, name/etc. from WorldInfo.Game - its configurable.
            o = "UTUIScene_MidGameMenu_" $ i ;
            Mnu = UTUIScene_MidGameMenu( FindObject( o $ i, class'UTGame.UTUIScene_MidGameMenu'));
            if( Mnu != None )
            {
                `BiaDbg("Closing the friggin-damned-console-lookin-MidGameMenu: " $ Mnu);
                Mnu.CloseScene(Mnu);
                break;
            }
        }
*/

        // This works - sorta...
        GRI = UTGameReplicationInfo(WorldInfo.GRI);
        if ( GRI != none && GRI.CurrentMidGameMenu != none )
        {
            GRI.CurrentMidGameMenu.CloseScene(GRI.CurrentMidGameMenu);
        }


        if( bShowWelcome && LP != None )
        {
            SceneClient = class'UIRoot'.static.GetSceneClient();
            if ( SceneClient != None )
            {
                `BiaDbg("Opening BiaWelcomeScene");
                SceneClient.OpenScene(BiaVoteWelcomeScene'BiaVoteMenu.BiaVoteWelcomeScene', LP );
            }
            else
            {
                `BiaDbg("Unable to get SceneClient!");
            }
        }
        else
        {
            `BiaError("Failed to get LocalPlayer");
        }
        
    }
}

function Initialize( PlayerController PC )
{
    MyPlayerController = PC;
    SetTimer(0.1, false, 'DoSync');
}

function DoSync()
{
    local bool bShow;
    ReadTheConfig();
    SetTimer(10.0,false,'CancelSync');
    bShow = class'BiaVote.BiaVote'.static.CanShowWelcomeScreen( MyPlayerController );
    ClientInitialize(MyPlayerController, bShow);
}

function StopSync(bool success)
{
    ClearTimer('SendData');
    ClearTimer('CancelSync');
    if(success)
    {
        GotoState('AllDone');
    }
    else
    {
        ClearTimer();
        GotoState('');
        `BiaError("Failed to sync UIData");
    }
}



function ReadTheConfig()
{
    local int i;
    local BiaVoteUIData U;
    local string s;
    
    aUIData.Length = 0;
    
    for(i=0; i< UIData.Length; i++)
    {
        U = UIData[i];
        if( U.Tag == "" )
        {
            `BiaError(".ini file is missing Tag= in entry " $ i $ " for " $ Class );
            continue;
        }
        if( U.Value == "" )
        {
            `BiaError(".ini file is missing Value= in entry " $ i $ " for " $ Class );
            continue;
        }
        U.List = "Labels";
        U.Index = i;
        aUIData.AddItem(U);
    }

    U.List = "Message";
    for(i = 0; i < WelcomeText.Length; i++ )
    {
        s = WelcomeText[i];
        U.Value = Left(s, min(80, Len(s)));
        U.Index = i;
        aUIData.AddItem(U);
    }
}

reliable client function ClientInitialize( PlayerController PC, bool bCanShow )
{
    local DataStoreClient DataStoreManager;

    bShowWelcome = bCanShow;
    
    SendIndex = 0;
    LP = LocalPlayer(PC.Player);
    
    if(LP != None )
    {
        self.static.SetDefaultLocalPlayer(LP);
        
        DataStoreManager = class'UIInteraction'.static.GetDataStoreClient();
        if( DataStoreManager != None )
        {
            Store = BiaVoteDataStore(DataStoreManager.FindDataStore('BiaVoteDataStore', LP));

            if( Store == None )
            {
                `BiaDbg("Creating new DatStore instance");
            
                Store = DataStoreManager.CreateDataStore(class'BiaVote.BiaVoteDataStore');
                `BiaDbg("Created data store? : " $ Store);
                if( Store != None )
                {
                    if( ! DataStoreManager.RegisterDataStore(Store, LP )) {
                        `BiaDbg("Failed to register data store!");
                    }
                    else
                    {
                        `BiaDbg("Register data store seems to have succeeded");
                    }
                }
            }
            
            Store = BiaVoteDataStore(DataStoreManager.FindDataStore('BiaVoteDataStore', LP));

            if( Store != None )
            {
                `BiaDbg("ready!");
                ServerClientReady();
                return;
            }
            else
            {
                `BiaError("can't get DataStore class");
            }
        }
        else
        {
            `BiaError("Can't get DataStoreManager");
        }
    }
    else
    {
        `BiaError("Can't get LocalPlayer!");
    }
}

reliable server function ServerClientReady()
{
    StartSync();
}

function StartSync()
{
    SendIndex = 0;
    SetTimer(0.1, true, 'SendData');
}


function CancelSync()
{
    `BiaError("Sync cancelled - timed out");
    StopSync(false);
}

function SendData() {
    if (SendIndex < aUIData.Length )
    {
        ClientSendData(SendIndex, aUIData[SendIndex]);
    }
    else
    {
        StopSync(true);
    }
}
reliable server function AckData()
{
    SendIndex += 1;
}

reliable client function ClientSendData( int Index, BiaVoteUIData U )
{
    local UIProviderScriptFieldValue Thing;
    if( Index == SendIndex ) // is this the one we're expecting...
    {
        SendIndex += 1;      // expect this one next...
        if( U.List ~= "Labels" )
        {
            Thing.StringValue = U.Tag $ ":" $ U.Value;
        }
        else
        {
            Thing.StringValue = U.Value;
        }
        Store.SetFieldValue(U.List, Thing, U.Index);
        AckData();
    }
}


// ---------------------------------------------------------------------------

//
// if no PC is passed, a previously passed LocalPlayer associated with
// it will be used - this should work fine as it is set in this class
// when the datastore is initialized (and needs to stay that way)
static function BiaVoteDataStore GetDS( optional PlayerController PC )
{
    local BiaVoteDataStore DS;
    local DataStoreClient DataStoreManager;
    local LocalPlayer LocalP;

    LocalP = GetDefaultLocalPlayer();
    
    if( PC != None )
    {
        LocalP = LocalPlayer(PC.Player);
        if( GetDefaultLocalPlayer() == None )
        {
            SetDefaultLocalPlayer(LocalP);
        }
    }
    else
    {
        LocalP = GetDefaultLocalPlayer();
    }
    

    DataStoreManager = class'UIInteraction'.static.GetDataStoreClient();

    if( DataStoreManager != None )
    {
        // Yeah, right... the 2nd arg don't seem to be so optional... (hence the stuff up there)
        DS = BiaVoteDataStore(DataStoreManager.FindDataStore('BiaVoteDataStore', LocalP));
        
        if( DS != None )
        {
            return DS;
        }
    }
    return None;
}

private static function SetDefaultLocalPlayer( LocalPlayer LocalP )
{
    local BiaVoteDataClient DC;
    DC = BiaVoteDataClient(FindObject("BiaVote.Default__BiaVoteDataClient", class'BiaVote.BiaVoteDataClient'));
    if( DC != None )
    {
        DC.LP = LocalP;
    }
}

private static function LocalPlayer GetDefaultLocalPlayer()
{
    local BiaVoteDataClient DC;
    DC = BiaVoteDataClient(FindObject("BiaVote.Default__BiaVoteDataClient", class'BiaVote.BiaVoteDataClient'));
    if( DC != None )
    {
        return DC.LP;
    }
    return None;
}



defaultproperties
{
    RemoteRole=ROLE_SimulatedProxy
    bAlwaysRelevant=True
    bSkipActorPropertyReplication=false
    Role=ROLE_Authority
    NetUpdateFrequency=1
}
